package my.graduation.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import my.graduation.dto.ExamModifyDto;
import my.graduation.entity.Clinic;
import my.graduation.entity.Department;
import my.graduation.entity.ExaminationModify;
import my.graduation.entity.RegistrationModify;
import my.graduation.enums.HttpCodeEnums;
import my.graduation.mapper.*;
import my.graduation.result.Result;
import my.graduation.service.ExaminationModifyService;
import my.graduation.vo.ExaminationModifyVO;
import my.graduation.vo.RegistrationModifyVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author: RavenLyn
 * @Date: 2024-12-16
 */
@Service
public class ExaminationModifyServiceImpl extends ServiceImpl<ExaminationModifyMapper, ExaminationModify> implements ExaminationModifyService {
    @Autowired
    private DepartmentMapper departmentMapper;
    @Autowired
    private ClinicMapper clinicMapper;
    @Autowired
    private ExaminationScheduleMapper examScheMapper;

    /**
     * 获取修改申请列表信息
     * @return
     */
    @Override
    public Result<List<ExaminationModifyVO>> getAllList() {
        List<ExaminationModify> list = list();
        return getListMethod(list);
    }

    /**
     * 条件获取修改申请列表
     * @param dto
     * @return
     */
    @Override
    public Result<List<ExaminationModifyVO>> getListByCon(ExamModifyDto dto) {
        List<ExaminationModify> list = list(Wrappers.<ExaminationModify>lambdaQuery()
                .eq(dto.getDepartmentId() != null, ExaminationModify::getDepartmentId, dto.getDepartmentId())
                .eq(dto.getClinicId() != null, ExaminationModify::getClinicId, dto.getClinicId())
                .like(dto.getDoctorName() != null, ExaminationModify::getDoctorName, dto.getDoctorName()));

        return getListMethod(list);
    }

    /**
     * 获取排班修改申请列表封装method
     * @param list
     * @return
     */
    public Result<List<ExaminationModifyVO>> getListMethod(List<ExaminationModify> list){
//        System.out.println(list.size());
        if(list.isEmpty()){
            return Result.success();
        }
        // 2 从list中提取所有的departmentId
        List<Integer> departIdList = list.stream()
                .map(ExaminationModify::getDepartmentId)
                .collect(Collectors.toList());
        // 从list中提取所有的clinicId
        List<Integer> clinicIdList = list.stream()
                .map(ExaminationModify::getClinicId)
                .collect(Collectors.toList());

        // 3 查询出 departmentList 和 clinicList
        List<Department> departmentList = departmentMapper.selectBatchIds(departIdList);
        List<Clinic> clinicList = clinicMapper.selectBatchIds(clinicIdList);

        // 4 封装成map，提高查询性能
        Map<Integer, String> departNameMap = departmentList.stream()
                .collect(Collectors.toMap(Department::getId, Department::getName));
        Map<Integer, String> clinicNameMap = clinicList.stream()
                .collect(Collectors.toMap(Clinic::getId, Clinic::getName));

        // 5 装到clinicVO中
        List<ExaminationModifyVO> voList = new ArrayList<>();
        for (ExaminationModify modifyOne : list){
            // 使用map集合，将O(n)降低成O(1)
            String departmentName = departNameMap.getOrDefault(modifyOne.getDepartmentId(),null);
            String clinicName = clinicNameMap.getOrDefault(modifyOne.getClinicId(),null);
            voList.add(new ExaminationModifyVO(modifyOne, departmentName,clinicName));
        }

        return Result.success(voList);
    }

    /**
     * 管理员批准医生修改检查排班申请
     * @param dto
     * @return
     */
    @Override
    @Transactional
    public Result accept(ExamModifyDto dto) {
        // 1 参数校验 id examScheId moDate moDay moShift
        if(dto.getId() != null &&
                dto.getExamScheId() != null &&
                dto.getMoDate() != null &&
                dto.getMoDay() != null &&
                dto.getMoShift() != null){

            // 2 用examScheId修改examination_schedule表中的status, date, day_of_week, shift
            examScheMapper.updateAcceptStatus(dto.getExamScheId(),dto.getMoDate(), dto.getMoDay(), dto.getMoShift());
            // 3 用id删除registration_modify表中的行
            removeById(dto.getId());
            return Result.success();
        }else {
            return Result.error(HttpCodeEnums.SYSTEM_ERROR);
        }
    }

    /**
     * 管理员拒绝医生修改检查排班申请
     * @param dto
     * @return
     */
    @Transactional
    @Override
    public Result reject(ExamModifyDto dto) {
        // 1 参数校验 id examScheId
        if(dto.getId() != null && dto.getExamScheId() != null){
            // 2 用examScheId修改examination_schedule表中的status=0
            examScheMapper.updateRejectStatus(dto.getExamScheId());
            // 3 用id删除registration_modify表中的行
            removeById(dto.getId());
            return Result.success();
        }else {
            return Result.error(HttpCodeEnums.SYSTEM_ERROR);
        }
    }
}
